//
//  PXRefreshControl.swift
//  SchoolDemo
//
//  Created by rimi on 16/10/9.
//  Copyright © 2016年 YQ. All rights reserved.
//

import UIKit
//临界点
fileprivate let PXRefreshOffse: CGFloat = 60

/// 刷新视图状态
///
/// - nomol:       普通状态（什么都不做）
/// - pulling:     超过临界点，如果放手就开始刷新
/// - willRefresh: 已经超过临界点，并且已经放手，准备开始刷新
enum PXRefreshState {
    case nomol
    case pulling
    case willRefresh
}

class PXRefreshControl: UIControl {

    //记录父视图
    fileprivate weak var scrollView: UIScrollView?
    //创建UI属性
    let refreshV = PXRefreshView.refreshV()
 
    init() {
        super.init(frame:CGRect())
        //设置UI
        setupUI()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setupUI()
    }
    //获得父类属性
    //这个方法是在执行addsubview 会调用，移除时也会调用
    override func willMove(toSuperview newSuperview: UIView?) {
        super.willMove(toSuperview: newSuperview)
        //判断一下
        guard let sv = newSuperview as? UIScrollView else {
            return
        }
        //记录父视图
        scrollView = sv
        //使用KVO添加父视图属性变化
        //KVO添加监听以后必须在当前视图销毁前移除，否则会直接崩溃
        //不同于通知，通知不移除时不会发生什么，但是会造成内存泄漏或重复添加
        sv.addObserver(self, forKeyPath: "contentOffset", options: [], context: nil)
   
    }
    //当前视图移除时会调用
    override func removeFromSuperview() {
        //移除监听
        superview?.removeObserver(self, forKeyPath: "contentOffset")
        super.removeFromSuperview()
    }
    //KOV的监听毁掉方法
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
       
        guard let sv = scrollView else {
            return
        }
        //获得高度
        let H = -(sv.contentOffset.y + sv.contentInset.top)
       //屏蔽向上滚出屏幕的功能
        if H < 0 {
            return
        }
        //如果是拖拽情况下
        if sv.isDragging {
            if H > PXRefreshOffse && refreshV.refreshState == .nomol {
                print("手放开就刷新数据")
                refreshV.refreshState = .pulling
                //没放手
                //状态下返回
            } else if H < PXRefreshOffse && refreshV.refreshState == .pulling {
                print("再用点力")
                refreshV.refreshState = .nomol
            }
        }else {
            //进入这里表示拖拽结束，如果超过临界点就开始刷新
            if refreshV.refreshState == .pulling {
//              beginRefreshing()
                //发送事件消息
                sendActions(for: .valueChanged)
            }
        }

        
        //设置空间高度
        self.frame = CGRect(x: 0, y: -H, width: UIScreen.main.bounds.width, height: H)
    }
    
    ///开始刷新
    func beginRefreshing(){
        guard let sv = scrollView else {
            return
        }
        if refreshV.refreshState == .willRefresh {
            return
        }
        //已经进入刷新数据状态
        refreshV.refreshState = .willRefresh
        
        //保持刷新状态
        var inset = sv.contentInset
        inset.top += PXRefreshOffse
        sv.contentInset = inset
    }
    
    ///结束刷新
    func endRefreshing(){
        guard let sv = scrollView else {
            return
        }
        if refreshV.refreshState != .willRefresh {
            return
        }
        //修改状态
        refreshV.refreshState = .nomol
        //调整父视图高度
        UIView.animate(withDuration: 2,animations: {
            var inset = sv.contentInset
            inset.top -= PXRefreshOffse
            sv.contentInset = inset
        })
    }
}

extension PXRefreshControl {
    //设置UI
     fileprivate func setupUI() {
        
//        backgroundColor = #colorLiteral(red: 0.2196078449, green: 0.007843137719, blue: 0.8549019694, alpha: 1)
        //添加视图
        addSubview(refreshV)
        
        //拖拽松手后图片会到0的上方，所以在调试结束后因取消裁剪超出边界的功能“clipsToBounds”
        //裁剪超出边界的内容
//        clipsToBounds = true
        //使用原生的约束框架,必须先关掉系统的自动设置约束的属性
        //storybook会自动关闭，纯代码需手动设置下面这个属性为false
        refreshV.translatesAutoresizingMaskIntoConstraints = false
        //设置中心X
        addConstraint(NSLayoutConstraint(item: refreshV,
                                         attribute: .centerX,
                                         relatedBy: .equal,
                                         toItem: self,
                                         attribute: .centerX,
                                         multiplier: 1.0,
                                         constant: 0))
        //设置中心Y
       addConstraint(NSLayoutConstraint(item: refreshV,
                                        attribute: .bottom,
                                        relatedBy: .equal,
                                        toItem: self,
                                        attribute: .bottom,
                                        multiplier: 1.0,
                                        constant: 0))
        //宽
        addConstraint(NSLayoutConstraint(item: refreshV,
                                         attribute: .width,
                                         relatedBy: .equal,
                                         toItem: nil,
                                         attribute: .notAnAttribute,
                                         multiplier: 1.0,
                                         constant: refreshV.bounds.width))
        //高
        addConstraint(NSLayoutConstraint(item: refreshV,
                                         attribute: .height,
                                         relatedBy: .equal,
                                         toItem: nil,
                                         attribute: .notAnAttribute,
                                         multiplier: 1.0,
                                         constant: refreshV.bounds.height))
    }
    
}
